package com.smedi.ismedi.notification.core.application.service.impl;

import cn.hutool.core.util.IdUtil;
import com.smedi.ismedi.notification.core.application.command.SendMailCommand;
import com.smedi.ismedi.notification.core.application.service.MailNotificationApplicationService;
import com.smedi.ismedi.notification.core.domain.aggregatemodel.MailLog;
import com.smedi.ismedi.notification.core.domain.aggregatemodel.MailTemplate;
import com.smedi.ismedi.notification.core.domain.aggregatemodel.SmsLog;
import com.smedi.ismedi.notification.core.domain.service.MailLogDomainService;
import com.smedi.ismedi.notification.core.domain.service.MailTemplateDomainService;
import com.smedi.ismedi.notification.core.infrastructure.constant.CustomError;
import com.smedi.ismedi.web.starter.exception.LogicException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.mail.internet.MimeMessage;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @className: MailNotificationApplicationServiceImpl
 * @Description: TODO
 * @version: v1.0.0
 * @author: wzx
 * @date: 2022/11/23 15:01
 */

@Slf4j
@Service
@RequiredArgsConstructor
public class MailNotificationApplicationServiceImpl implements MailNotificationApplicationService {

    private final MailTemplateDomainService mailTemplateDomainService;

    private final MailLogDomainService mailLogDomainService;

    private final JavaMailSender javaMailSender;

    @Value("${spring.mail.username}")
    private String username;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void sendMail(SendMailCommand sendMailCommand) {
        MailTemplate mailTemplate = null;
        // 获取短信模板
        if (null != sendMailCommand.getMailTemplateId()) {
            mailTemplate = mailTemplateDomainService.queryTemplateByMailTemplateId(sendMailCommand.getMailTemplateId());
        }
        if (null != sendMailCommand.getMailTemplateName()) {
            mailTemplate = mailTemplateDomainService.queryTemplateByMailTemplateName(sendMailCommand.getMailTemplateName());
        }
        if(mailTemplate == null){
            throw LogicException.raise(CustomError.MAIL_TEMPLATE_NOT_FOUND);
        }
        // 校验接收人员
        List<String> mails = sendMailCommand.getReceivers();
        if (mails.size() == 0) {
            throw LogicException.raise(CustomError.RECEIVERS_EMPTY);
        }
        // 校验参数与模板是否匹配
        if (mailTemplate.getParameters() != sendMailCommand.getParameters().size()) {
            throw LogicException.raise(CustomError.PARAMETERS_NOT_FIX_TEMPLATE);
        }

        // 生成batchId
        String batchId = IdUtil.objectId();
        // 获取实际发送的邮件信息
        String actualMailContent = mailTemplate.getTemplateContent();
        for (int i = 1; i <= mailTemplate.getParameters(); i++) {
            actualMailContent = actualMailContent.replaceAll("\\{" + i + "\\}", sendMailCommand.getParameters().get(i - 1));
        }

        // 发送短信信息
        List<MailLog> mailLogs = new ArrayList<>();

        try {
            MimeMessage message = javaMailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            //邮件发件人
            helper.setFrom(username);
            //邮件收件人 1或多个
            helper.setTo(mails.toArray(new String[mails.size()]));
            //邮件主题
            helper.setSubject(mailTemplate.getTemplateName());
            //邮件内容
            helper.setText(actualMailContent);
            //邮件发送时间
            helper.setSentDate(new Date());
            javaMailSender.send(message);
            mailLogs.add(new MailLog()
                    .setBatchId(batchId)
                    .setMessageContent(actualMailContent)
                    .setMailNum(mails.toString())
                    .setTemplateId(sendMailCommand.getMailTemplateId())
                    .setSucceed(true));


        } catch (Exception e) {
            for (String mail : mails) {
                mailLogs.add(new MailLog()
                        .setBatchId(batchId)
                        .setMessageContent(actualMailContent)
                        .setMailNum(mail)
                        .setTemplateId(sendMailCommand.getMailTemplateId())
                        .setSucceed(false)
                        .setErrorMessage(e.getMessage()));
            }
        }

        mailLogDomainService.batchSaveMailsLogs(mailLogs);
    }
}